﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using SegIdenPC.Utilitarios;
using SegIdenPC.Entidad;
using log4net;
using System.Configuration;
using GS1.Utilitario;
using SegIdenPC.Herramientas;

namespace SegIdenPC.Formularios
{
    public partial class frmGuiaImprimir : Form
    {
        #region --- Variables y Propiedades ---
        private static readonly ILog log = LogManager.GetLogger(typeof(frmVentaImprimir));

        // Formateo Monto
        private const string FORMATO_MONTO = "#0.00";

        private const string ETIQUETA_SUBTOTAL = "SubTotal";
        private const string ETIQUETA_TOTAL = "Total";

        private const string LLAVE_DIRECCIONIMPRESORA = "DIRECCIONIMPRESORA";

        private Guia guiaActual = null;

        private const string TITULO = "Imprimir Guia";
        #endregion

        #region --- Constructor ---
        public frmGuiaImprimir()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Eventos Formulario ---
        private void frmGuiaImprimir_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }

        private void btnImprimir_Click(object sender, EventArgs e)
        {
            imprimirDocumento();
        }

        private void btnBuscar_Click(object sender, EventArgs e)
        {
            buscarGuia();
        }

        private void tbtnSalir_Click(object sender, EventArgs e)
        {
            salir();
        }

        #endregion

        #region --- Metodos Propios ---

        private void cargarFormulario()
        {
            this.txtSerie.Focus();
        }

        private void tbtnImprimir_Click(object sender, EventArgs e)
        {
            imprimirDocumento();
            
        }

        private void imprimirDocumento()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;
            
            ImprimirDocumento imprimirDocumento = null;

            try
            {
                if (this.guiaActual == null) { return; }

                this.Cursor = Cursors.WaitCursor;

                // Solicitar confirmacion
                if (!Libreria.ShowMessageboxPregunta("¿Estas seguro de Imprimir la Guia?", TITULO)) { return; }

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_MODIFICAR_GUIA;

                operacion.guia = guiaActual;

                // Estableciendo estado 
                operacion.guia.estado = Constantes.ESTADO_DOCUMENTO_IMPRESO;

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {

                    imprimirDocumento = new ImprimirDocumento(this.guiaActual);
                    imprimirDocumento.establecerImpresora(ConfigurationManager.AppSettings[LLAVE_DIRECCIONIMPRESORA]);

                    imprimirDocumento.ejecutarGuia();

                    Libreria.ShowMessageboxInfo("Finalizó proceso de impresión", TITULO);
                }
                else
                {
                    Libreria.ShowMessageboxError("No se realizó la impresión", TITULO);
                    return;
                }

                
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, this.Text);
            }
            finally
            {
                this.Cursor = Cursors.Default;
            }

            
        }

        private bool validarEntradaBusqueda()
        {
            this.txtSerie.Text = this.txtSerie.Text.Trim();
            this.txtNumero.Text = this.txtNumero.Text.Trim();

            if (this.txtNumero.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtNumero, "Debes ingresa el número de documento");
                return true;
            }

            if (this.txtSerie.Text.Equals(string.Empty))
            {
                Libreria.CampoNecesario(this.txtSerie, "Debes ingresar la serie del documento");
                return true;
            }

            return false;
        }

        private void buscarGuia()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                if (validarEntradaBusqueda()) { return; }

                Cursor.Current = Cursors.WaitCursor;

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_OBTENER_GUIA;

                operacion.guia = new Guia();

                operacion.guia.serie = this.txtSerie.Text.Trim();
                operacion.guia.numero = this.txtNumero.Text.Trim();

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                // Obteniendo Objeto de Cliente
                Guia guia = contenidoXML.DeserializarTo<Guia>();

                // Si la venta existe
                if (guia != null)
                {
                    if (guia.estado.Equals(Constantes.ESTADO_DOCUMENTO_IMPRESO))
                    {
                        Libreria.ShowMessageboxExclamacion("Este documento ya ha sido impreso", this.Text);
                        return;
                    }

                    this.guiaActual = guia;

                    // Establecer los datos en la pantalla
                    //Las guias de CD tienen como origen una tienda
                    this.txtTiendaODescripcion.Text = this.guiaActual.tiendaOrigen.nombre;
                    
                    //El destino se ve de acuerdo al tipo de guia
                    //Si es Transferencia
                    if (this.guiaActual.tiendaDestino != null) this.txtTiendaDDescripcion.Text = this.guiaActual.tiendaDestino.nombre;
                    //Si es Venta 
                    if (this.guiaActual.venta != null) this.txtTiendaDDescripcion.Text = this.guiaActual.venta.cliente.razonSocial;
                    //Si es prestamo
                    if (this.guiaActual.prestamo != null) this.txtTiendaDDescripcion.Text = this.guiaActual.prestamo.cliente.razonSocial;
                    //Si es mantenimiento
                    if (this.guiaActual.mantenimiento != null) this.txtTiendaDDescripcion.Text = this.guiaActual.mantenimiento.proveedor.razonSocial;
                    
                    //debe preguntar si la lista de las guias tiene más de 25 lineas
                    if (guiaActual.listaLineaGuia.lista.Count > 25)
                    {
                        Libreria.ShowMessageboxExclamacion("La guia no se podrá imprimir en todo el documento. Se separará el contenido", this.Text);
                        
                        //Se crean las nuevas guias donde estarán los registros que sobraron
                        Guia guiaNueva = new Guia();
                        Guia guiaAnterior = new Guia();

                        //Se cargan los datos sobre la Guia Nueva
                        guiaNueva.codGuia = Constantes.VALOR_CERO;
                        guiaNueva.estado = guiaActual.estado;
                        guiaNueva.fechaEmision = guiaActual.fechaEmision;
                        guiaNueva.fechaRegistro = guiaActual.fechaRegistro;
                        if (guiaActual.mantenimiento !=null)
                        {
                             guiaNueva.mantenimiento = new Mantenimiento();
                             guiaNueva.mantenimiento = guiaActual.mantenimiento;
                        }
                        if (guiaActual.prestamo !=null)
                        {
                            guiaNueva.prestamo = new Prestamo();
                            guiaNueva.prestamo = guiaActual.prestamo;
                        }
                        if (guiaNueva.solicitud != null)
                        {
                            guiaNueva.solicitud = new Solicitud();
                            guiaNueva.solicitud = guiaActual.solicitud;
                            guiaNueva.tiendaDestino = new Tienda();
                            guiaNueva.tiendaDestino = guiaActual.tiendaDestino;
                        }

                        guiaNueva.tiendaOrigen = new Tienda();
                        guiaNueva.tiendaOrigen = guiaActual.tiendaOrigen;
                        guiaNueva.tipoGuia = new TipoGuia();
                        guiaNueva.tipoGuia = guiaActual.tipoGuia;
                        if (guiaNueva.transporte != null)
                        {
                            guiaNueva.transporte = new Transporte();
                            guiaNueva.transporte = guiaActual.transporte;
                        }

                        if (guiaNueva.venta != null)
                        {
                            guiaNueva.venta = new Venta();
                            guiaNueva.venta = guiaActual.venta;
                        }

                        //Se cargan los datos sobre la Guia Anterior para reemplazar a la guia Actual
                        guiaAnterior.codGuia = guiaActual.codGuia;
                        guiaAnterior.numero = guiaActual.numero;
                        guiaAnterior.serie = guiaActual.serie;

                        guiaAnterior.estado = guiaActual.estado;
                        guiaAnterior.fechaEmision = guiaActual.fechaEmision;
                        guiaAnterior.fechaRegistro = guiaActual.fechaRegistro;
                        
                        if (guiaActual.mantenimiento != null)
                        {
                            guiaAnterior.mantenimiento = new Mantenimiento();
                            guiaAnterior.mantenimiento = guiaActual.mantenimiento;
                        }
                        
                        if (guiaActual.prestamo != null)
                        {
                            guiaAnterior.prestamo = new Prestamo();
                            guiaAnterior.prestamo = guiaActual.prestamo;
                        }
                        
                        if (guiaAnterior.solicitud != null)
                        {
                            guiaAnterior.solicitud = new Solicitud();
                            guiaAnterior.solicitud = guiaActual.solicitud;
                            guiaAnterior.tiendaDestino = new Tienda();
                            guiaAnterior.tiendaDestino = guiaActual.tiendaDestino;
                        }

                        guiaAnterior.tiendaOrigen = new Tienda();
                        guiaAnterior.tiendaOrigen = guiaActual.tiendaOrigen;
                        guiaAnterior.tipoGuia = new TipoGuia();
                        guiaAnterior.tipoGuia = guiaActual.tipoGuia;
                        
                        if (guiaAnterior.transporte != null)
                        {
                            guiaAnterior.transporte = new Transporte();
                            guiaAnterior.transporte = guiaActual.transporte;
                        }

                        if (guiaAnterior.venta != null)
                        {
                            guiaAnterior.venta = new Venta();
                            guiaAnterior.venta = guiaActual.venta;
                        }

                        //Se crean las listas de las lineas que sobraron
                        ListaLineaGuia listaLineaGuiaNueva = new ListaLineaGuia();
                        ListaLineaGuia listaLineaGuiaAnterior = new ListaLineaGuia();

                        //Se debe cortar la lista no debe esperar a mandar a imprimir 
                        int iContador = 0;

                        foreach (LineaGuia lineaGuiaActual in guiaActual.listaLineaGuia.lista)
                        {
                            if (iContador < 24)
                            {
                                LineaGuia lineaGuiaAnterior = new LineaGuia();
                                lineaGuiaAnterior.cantidad = lineaGuiaActual.cantidad;
                                lineaGuiaAnterior.codGuia = lineaGuiaActual.codGuia;
                                lineaGuiaAnterior.numeroLinea = lineaGuiaActual.numeroLinea;
                                lineaGuiaAnterior.producto = new Producto();
                                lineaGuiaAnterior.producto = lineaGuiaActual.producto;
                                lineaGuiaAnterior.listaLineaGuiaItem = new ListaLineaGuiaItem();
                                lineaGuiaAnterior.listaLineaGuiaItem = lineaGuiaActual.listaLineaGuiaItem;
                                
                                listaLineaGuiaAnterior.add(lineaGuiaAnterior);
                            }
                            else
                            {
                                LineaGuia lineaGuiaNueva = new LineaGuia();
                                lineaGuiaNueva.cantidad = lineaGuiaActual.cantidad;
                                lineaGuiaNueva.codGuia = Constantes.VALOR_CERO;
                                lineaGuiaNueva.numeroLinea = lineaGuiaActual.numeroLinea;
                                lineaGuiaNueva.producto = new Producto();
                                lineaGuiaNueva.producto = lineaGuiaActual.producto;
                                lineaGuiaNueva.listaLineaGuiaItem = new ListaLineaGuiaItem();
                                lineaGuiaNueva.listaLineaGuiaItem = lineaGuiaActual.listaLineaGuiaItem;

                                listaLineaGuiaNueva.add(lineaGuiaNueva);
                            }
                            iContador++;
                        }

                        //Se registra la lista hasta los 23 primeras lineas
                        guiaAnterior.listaLineaGuia = new ListaLineaGuia();
                        guiaAnterior.listaLineaGuia = listaLineaGuiaAnterior;
                        //Se registra el resto de las lineas
                        guiaNueva.listaLineaGuia = new ListaLineaGuia();
                        guiaNueva.listaLineaGuia = listaLineaGuiaNueva;

                        // Se debe llamar a una ventana para registrar el nuevo número de la venta y jalar los datos de la Lista linea Venta con sus Items
                        using (frmDocSerieNumeroAgregar frmDocSerieNumeroAgregar = new frmDocSerieNumeroAgregar())
                        {
                            frmDocSerieNumeroAgregar.guia = guiaNueva;

                            if (frmDocSerieNumeroAgregar.ShowDialog() == DialogResult.Cancel) { frmDocSerieNumeroAgregar.Dispose(); return; }

                            guiaNueva.serie = frmDocSerieNumeroAgregar.guia.serie;
                            guiaNueva.numero = frmDocSerieNumeroAgregar.guia.numero;

                            frmDocSerieNumeroAgregar.Dispose();
                        }
                        //Se graba la nueva guia y se actualiza la guia anterior
                        separarGuia(guiaAnterior, guiaNueva);

                        //Se actualiza los datos que se van a imprimir y mostrar
                        guiaActual.listaLineaGuia = new ListaLineaGuia();
                        guiaActual.listaLineaGuia = guiaAnterior.listaLineaGuia;

                    }
                    
                    // Se establece propiedad para evitar que genere nuevas columnas que no estan mapeadas en la grilla
                    this.dgvListadoItemsSeleccionados.AutoGenerateColumns = false;

                    this.dgvListadoItemsSeleccionados.DataSource = guiaActual.listaLineaGuia.lista == null ?
                                                            new ListPersonalizada<LineaGuia>() :
                                                            guiaActual.listaLineaGuia.lista;

                    pintarGrilla(this.dgvListadoItemsSeleccionados);

                }
                else
                {
                    Libreria.ShowMessageboxExclamacion("El registro de la guia buscada no existe", this.Text);
                    return;
                }
            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void separarGuia(Guia guiaAnterior, Guia guiaNueva)
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_ACTUALIZAR_GUIA;

                //Cargando los datos de las ventas
                operacion.guiaActual = guiaAnterior;
                operacion.guiaNueva = guiaNueva;

                // Instanciando y ejecutando llamada al ServicioREST
                ConexionREST conexionREST = new ConexionREST();
                contenidoXML = conexionREST.ejecutarOperacion(operacion);

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Libreria.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {
                    //this.txtCodigo.Text = operacionResultado.codigoGenerado;
                    Libreria.ShowMessageboxInfo("Guia guardada correctamente", TITULO);
                }
                else
                {
                    Libreria.ShowMessageboxError("No se guardo los datos", TITULO);
                    return;
                }


            }
            catch (Exception ex)
            {
                log.Error(ex.Message, ex);
                Libreria.MensajeError(ex, TITULO);
            }
        }


        private void pintarGrilla(DataGridView grilla)
        {
            ListPersonalizada<LineaGuia> listaLineaGuia = null;
            listaLineaGuia = (ListPersonalizada<LineaGuia>)grilla.DataSource;

            if (listaLineaGuia != null)
            {
                for (int i = 0; i < listaLineaGuia.Count; i++)
                {
                    LineaGuia lineaGuia = listaLineaGuia[i];
                    grilla.Rows[i].Cells[1].Value = lineaGuia.producto.codProductoProveedor;

                    grilla.Rows[i].Cells[3].Value = lineaGuia.producto.nivelProducto.descripcion + " " +
                        lineaGuia.producto.nivelTipo.descripcion + " " +
                        lineaGuia.producto.nivelMaterial.descripcion + " " +
                        lineaGuia.producto.nivelColor.descripcion;
                }
            }
        }

        private void salir()
        {
            this.Close();
        }

        #endregion
    }
}
